package com.zxj;

import lombok.Builder;
import lombok.Data;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.Arrays;

public class HBaseTest {

    private static Admin admin;

    static {
        try {
            admin = initAdmin();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建连接
     * @return
     * @throws IOException
     */
    private static Admin initAdmin() throws IOException{
        Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "192.168.44.128");
        configuration.set("hbase.zookeeper.property.clientPort", "2181");
        configuration.set("hbase.master", "192.168.44.128:60000");
        Connection conn = ConnectionFactory.createConnection(configuration);
        return conn.getAdmin();
    }

    /**
     * 创建表
     * @param namespace
     * @param tableName
     * @param colFamilies
     * @throws IOException
     */
    private static void createTable(String namespace, String tableName, String... colFamilies) throws IOException {
        // namespace若不存在则创建
        NamespaceDescriptor[] nss = admin.listNamespaceDescriptors();
        if (Arrays.stream(nss).noneMatch(vo -> vo.getName().equals(namespace))) {
            admin.createNamespace(NamespaceDescriptor.create(namespace).build());
            System.out.println("创建namespace：" + namespace);
        }
        // 表不存在则创建
        if (!admin.tableExists(TableName.valueOf(tableName))) {
            TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName));
            for (String cf : colFamilies) {
                builder.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(cf)).build());
            }
            admin.createTable(builder.build());
            System.out.println("创建表：" + tableName + "，列族：" + Arrays.asList(colFamilies));
        }
    }

    /**
     * 插入数据
     * @param tableData
     * @throws IOException
     */
    private static void putData(TableData tableData) throws IOException {
        Put put = new Put(Bytes.toBytes(tableData.getRowKey())); // row key
        put.addColumn(Bytes.toBytes(tableData.getColFamily()), Bytes.toBytes(tableData.getQualifier()), Bytes.toBytes(tableData.getValue())); // col1
        admin.getConnection().getTable(TableName.valueOf(tableData.getTable())).put(put);
        System.out.println("插入数据成功：" + tableData);
    }

    /**
     * 查询数据
     * @param tableData
     * @throws IOException
     */
    private static void getData(TableData tableData) throws IOException {
        Get get = new Get(Bytes.toBytes(tableData.getRowKey()));
        if (!get.isCheckExistenceOnly()) {
            Result result = admin.getConnection().getTable(TableName.valueOf(tableData.getTable())).get(get);
            for (Cell cell : result.rawCells()) {
                String colName = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
                String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
                System.out.println("查询数据成功：col:" + colName + ", value: " + value);
            }
        }
    }

    /**
     * 删除数据
     * @param tableData
     * @throws IOException
     */
    private static void delData(TableData tableData) throws IOException {
        Delete delete = new Delete(Bytes.toBytes(tableData.getRowKey()));      // 指定rowKey
        admin.getConnection().getTable(TableName.valueOf(tableData.getTable())).delete(delete);
        System.out.println("删除数据：" + tableData);
    }

    /**
     * 删除表
     * @param tableData
     * @throws IOException
     */
    private static void delTable(TableData tableData) throws IOException {
        if (admin.tableExists(TableName.valueOf(tableData.getTable()))) {
            admin.disableTable(TableName.valueOf(tableData.getTable()));
            admin.deleteTable(TableName.valueOf(tableData.getTable()));
            System.out.println("删除表：" + tableData);
        } else {
            System.out.println("要删除的表不存在！");
        }
    }

    public static void main(String[] args) throws IOException {
        // 创建表
        createTable("zhouxingjia", "zhouxingjia:student", "info", "score");
        // 插入数据
        putData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").colFamily("info").qualifier("student_id").value("G20210579070216").build());
        putData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").colFamily("info").qualifier("class").value("1").build());
        putData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").colFamily("score").qualifier("understanding").value("100").build());
        putData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").colFamily("score").qualifier("programming").value("100").build());
        // 查询数据
        getData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").build());
        // 删除数据
        delData(TableData.builder().table("zhouxingjia:student").rowKey("zhouxingjia").build());
        // 删除表
        delTable(TableData.builder().table("zhouxingjia:student").build());

    }

    @Builder
    @Data
    private static class TableData {

        private String table;
        private String rowKey;
        private String colFamily;
        private String qualifier;
        private String value;
    }

}
